package com.example.selenium.queue.rabbitmq.config;

import com.example.selenium.queue.rabbitmq.confirm.ConfirmCallbackService;
import com.example.selenium.queue.rabbitmq.confirm.ReturnCallbackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class RabbitConfig {

    @Autowired
    private MqProperties mqProperties;

    @Autowired
    private ConfirmCallbackService confirmCallbackService;

    @Autowired
    private ReturnCallbackService returnCallbackService;

    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory cachingConnectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(cachingConnectionFactory);

        // 开启Mandatory, 才能触发回调函数，无论消息推送结果如何都强制调用回调函数
        rabbitTemplate.setMandatory(true);

        // 消费者确认收到消息后，手动ack回执回调处理
        rabbitTemplate.setConfirmCallback(confirmCallbackService);

        // 消息投递到队列失败回调处理
        rabbitTemplate.setReturnCallback(returnCallbackService);

        return rabbitTemplate;
    }

    /**
     * mq 连接工厂
     * @return
     */
    @Bean
    public ConnectionFactory cachingConnectionFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setHost(mqProperties.getHost());
        factory.setPort(mqProperties.getPort());
        factory.setUsername(mqProperties.getUsername());
        factory.setPassword(mqProperties.getPassword());
        // 这里要单独设置 消息发送确认以及返回 ，配置文件中配置不生效，也不知道为什么
        factory.setPublisherReturns(true);
        factory.setSimplePublisherConfirms(true);
        return factory;
    }
}
